library(rgl)
knitr::knit_hooks$set(webgl = hook_webgl)
Scalable Vector Graphics, abbreviated: SVG, is an XML-based file format for static and dynamic vector graphics. It is an open standard of the W3C. Inkscape is an open source vector illustration program that uses the SVG format to store vector graphics. We start our analyses from checking Inkscape installation
This is the Scalable Vector Graphic we want to analyze:
url <- 'https://upload.wikimedia.org/wikipedia/commons/1/1b/Red_Bird.svg'
knitr::include_graphics(url)
As far there is no easy way to import SVG file, convert it into Simple Features and analyze using R. That’s why we gonna use an external powerful and beautiful tool which is Inkscape.
system('inkscape --version', intern = TRUE)
## [1] "Inkscape 1.2.1 (9c6d41e410, 2022-07-14)"
We can use dedicated R package https://github.com/JacekPardyak/inkscaper.
devtools::install_github("JacekPardyak/inkscaper")
## Skipping install of 'inkscaper' from a github remote, the SHA1 (7714a2a4) has not changed since last install.
## Use `force = TRUE` to force installation
library(inkscaper)
Function to convert SVG into SF
logo <- url %>%
inx_svg2sf() %>%
select(geometry) %>%
st_union() %>%
st_polygonize() %>%
first()
## Reading layer `entities' from data source
## `C:\Users\Jacek Pardyak\AppData\Local\Temp\RtmpKE1p46\inx_43c467547628.dxf'
## using driver `DXF'
## Simple feature collection with 2797 features and 6 fields
## Geometry type: LINESTRING
## Dimension: XY
## Bounding box: xmin: 22.41016 ymin: 5.324796 xmax: 103.6297 ymax: 87.57702
## CRS: NA
logo %>% ggplot() +
geom_sf()
result <- st_sfc() %>% st_sf(geometry = .)
for(i in c(1: length(logo))) {
tmp <- logo %>%
nth(i) %>%
st_sfc() %>% st_sf(geometry = .) %>% mutate(facet = i)
result <- tmp %>% bind_rows(result)
}
result %>% ggplot() +
geom_sf() +
geom_sf_label(aes(label = facet)) +
theme_void()
result %>% plot_ly(split = ~facet)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
result %>% st_write("Red_Bird.shp", append=FALSE)
## Deleting layer `Red_Bird' using driver `ESRI Shapefile'
## Writing layer `Red_Bird' to data source `Red_Bird.shp' using driver `ESRI Shapefile'
## Writing 92 features with 1 fields and geometry type Polygon.
logo <- st_read("./Red_Bird.shp") %>% filter(!facet %in%
c(3:55, 56:60, 81)) %>% st_union()
## Reading layer `Red_Bird' from data source
## `C:\Users\Jacek Pardyak\Documents\JacekPardyak.github.io\inkscaper\Red_Bird.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 92 features and 1 field
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 22.41016 ymin: 5.324796 xmax: 103.6297 ymax: 87.57702
## CRS: NA
logo %>% ggplot() +
geom_sf() +
theme_void()
result <- st_read("./Red_Bird.shp") %>% filter(!facet %in%
c(3:55, 56:60, 81)) %>% st_union() %>% st_sfc() %>% st_sf()
## Reading layer `Red_Bird' from data source
## `C:\Users\Jacek Pardyak\Documents\JacekPardyak.github.io\inkscaper\Red_Bird.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 92 features and 1 field
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 22.41016 ymin: 5.324796 xmax: 103.6297 ymax: 87.57702
## CRS: NA
result
## Simple feature collection with 1 feature and 0 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 22.41016 ymin: 5.324796 xmax: 103.6297 ymax: 87.57702
## CRS: NA
## geometry
## 1 MULTIPOLYGON (((55.96632 7....
result %>% ggplot() +
geom_sf()
result
## Simple feature collection with 1 feature and 0 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 22.41016 ymin: 5.324796 xmax: 103.6297 ymax: 87.57702
## CRS: NA
## geometry
## 1 MULTIPOLYGON (((55.96632 7....
grid_spacing = 1
grid <- result %>% st_make_grid(what = "centers", cellsize = c(grid_spacing, grid_spacing)) %>%
st_sf()
heights <- st_join(grid, (result %>% select(geometry) %>% mutate(Z = 1))) %>% replace(is.na(.), 0)
z <- heights %>% st_coordinates() %>% as_tibble() %>%
bind_cols(heights %>% st_drop_geometry()) %>%
mutate(X = round(X,1)) %>%
mutate(Y = round(Y,1)) %>% pivot_wider(names_from = Y, values_from = Z) %>%
column_to_rownames("X") %>% as.matrix()
x <- 1:nrow(z)
y <- 1:ncol(z)
colorlut <- c("#F2F2F2", "#E34234") #"#ECB176",
col <- colorlut[ z - min(z) + 1 ] # assign colors to heights for each point
#open3d()
surface3d(x, y, z, color = col, back = "lines")
#e34234
#close3d()
library(gganimate)
result_1 <- st_read("./Red_Bird.shp") %>% filter(!facet %in%
c(3:55, 56:60, 81)) %>% st_union() %>% st_sfc() %>% st_sf() %>%
mutate(facet = 1)
## Reading layer `Red_Bird' from data source
## `C:\Users\Jacek Pardyak\Documents\JacekPardyak.github.io\inkscaper\Red_Bird.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 92 features and 1 field
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 22.41016 ymin: 5.324796 xmax: 103.6297 ymax: 87.57702
## CRS: NA
result_2 <- st_read("./Red_Bird.shp") %>% filter(facet %in%
c(3:55, 56:60, 81)) %>% st_union() %>% st_sfc() %>% st_sf() %>%
mutate(facet = 2)
## Reading layer `Red_Bird' from data source
## `C:\Users\Jacek Pardyak\Documents\JacekPardyak.github.io\inkscaper\Red_Bird.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 92 features and 1 field
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 22.41016 ymin: 5.324796 xmax: 103.6297 ymax: 87.57702
## CRS: NA
result <- result_1 %>% bind_rows(result_2)
result %>% ggplot() +
geom_sf() +
transition_states(
facet,
transition_length = 2,
state_length = 1
) +
enter_fade() +
exit_shrink() +
ease_aes('sine-in-out')
While obviously Inkscape is primarily intended as a GUI application, it can be used for doing SVG processing on the command line as well. Inkscape Actions available in versions Inkscape 1.2.1 (9c6d41e410, 2022-07-14) are listed below.
Inkscape Extensions are small programs that extend Inkscape’s functionality. They can provide features for specific tasks, experimentation, or art styles. They can also add support for special hardware or different export formats. While many extensions are included with Inkscape, you can also install extensions written by third parties or write your own. The table below shows the list of extensions available in Inkscape of version Inkscape 1.2.1 (9c6d41e410, 2022-07-14) with descriptions.
Result of the call
system('inkscape --help', intern = TRUE)
## [1] "Usage:"
## [1] " org.inkscape.Inkscape [OPTION…] file1 [file2 [fileN]]"
## [1] ""
## [1] "Process (or open) one or more files."
## [1] ""
## [1] "Help Options:"
## [1] " -?, --help Show help options"
## [1] " --help-all Show all help options"
## [1] " --help-gapplication Show GApplication options"
## [1] " --help-gtk Show GTK+ Options"
## [1] ""
## [1] "Application Options:"
## [1] " -V, --version Print Inkscape version"
## [1] " --debug-info Print debugging information"
## [1] " --system-data-directory Print system data directory"
## [1] " --user-data-directory Print user data directory"
## [1] " --app-id-tag Create a unique instance of Inkscape with the application ID 'org.inkscape.Inkscape.TAG'"
## [1] " --\b\b "
## [1] "File import: "
## [1] " -p, --pipe Read input file from standard input (stdin)"
## [1] " --pdf-page=PAGE PDF page number to import"
## [1] " --pdf-poppler Use poppler when importing via commandline"
## [1] " --convert-dpi-method=METHOD Method used to convert pre-0.92 document dpi, if needed: [none|scale-viewbox|scale-document]"
## [1] " --no-convert-text-baseline-spacing Do not fix pre-0.92 document's text baseline spacing on opening"
## [1] " --\b\b "
## [1] "File export: "
## [1] " -o, --export-filename=FILENAME Output file name (defaults to input filename; file type is guessed from extension if present; use '-' to write to stdout)"
## [1] " --export-overwrite Overwrite input file (otherwise add '_out' suffix if type doesn't change)"
## [1] " --export-type=TYPE[,TYPE]* File type(s) to export: [svg,png,ps,eps,pdf,emf,wmf,xaml]"
## [1] " --export-extension=EXTENSION-ID Extension ID to use for exporting"
## [1] " --\b\b "
## [1] "Export geometry: "
## [1] " -C, --export-area-page Area to export is page"
## [1] " -D, --export-area-drawing Area to export is whole drawing (ignoring page size)"
## [1] " -a, --export-area=x0:y0:x1:y1 Area to export in SVG user units"
## [1] " --export-area-snap Snap the bitmap export area outwards to the nearest integer values"
## [1] " -d, --export-dpi=DPI Resolution for bitmaps and rasterized filters; default is 96"
## [1] " -w, --export-width=WIDTH Bitmap width in pixels (overrides --export-dpi)"
## [1] " -h, --export-height=HEIGHT Bitmap height in pixels (overrides --export-dpi)"
## [1] " --export-margin=MARGIN Margin around export area: units of page size for SVG, mm for PS/PDF"
## [1] " --\b\b "
## [1] "Export options: "
## [1] " -i, --export-id=OBJECT-ID[;OBJECT-ID]* ID(s) of object(s) to export"
## [1] " -j, --export-id-only Hide all objects except object with ID selected by export-id"
## [1] " -l, --export-plain-svg Remove Inkscape-specific SVG attributes/properties"
## [1] " --export-ps-level=LEVEL Postscript level (2 or 3); default is 3"
## [1] " --export-pdf-version=VERSION PDF version (1.4 or 1.5); default is 1.5"
## [1] " -T, --export-text-to-path Convert text to paths (PS/EPS/PDF/SVG)"
## [1] " --export-latex Export text separately to LaTeX file (PS/EPS/PDF)"
## [1] " --export-ignore-filters Render objects without filters instead of rasterizing (PS/EPS/PDF)"
## [1] " -t, --export-use-hints Use stored filename and DPI hints when exporting object selected by --export-id"
## [1] " -b, --export-background=COLOR Background color for exported bitmaps (any SVG color string)"
## [1] " -y, --export-background-opacity=VALUE Background opacity for exported bitmaps (0.0 to 1.0, or 1 to 255)"
## [1] " --export-png-color-mode=COLOR-MODE Color mode (bit depth and color type) for exported bitmaps (Gray_1/Gray_2/Gray_4/Gray_8/Gray_16/RGB_8/RGB_16/GrayAlpha_8/GrayAlpha_16/RGBA_8/RGBA_16)"
## [1] " --export-png-use-dithering=false|true Force dithering or disables it"
## [1] " --\b\b "
## [1] "Query object/document geometry: "
## [1] " -I, --query-id=OBJECT-ID[,OBJECT-ID]* ID(s) of object(s) to be queried"
## [1] " -S, --query-all Print bounding boxes of all objects"
## [1] " -X, --query-x X coordinate of drawing or object (if specified by --query-id)"
## [1] " -Y, --query-y Y coordinate of drawing or object (if specified by --query-id)"
## [1] " -W, --query-width Width of drawing or object (if specified by --query-id)"
## [1] " -H, --query-height Height of drawing or object (if specified by --query-id)"
## [1] " --\b\b "
## [1] "Advanced file processing: "
## [1] " --vacuum-defs Remove unused definitions from the <defs> section(s) of document"
## [1] " --select=OBJECT-ID[,OBJECT-ID]* Select objects: comma-separated list of IDs"
## [1] " --\b\b "
## [1] " --actions=ACTION(:ARG)[;ACTION(:ARG)]* List of actions (with optional arguments) to execute"
## [1] " --action-list List all available actions"
## [1] " --\b\b "
## [1] "Interface: "
## [1] " -g, --with-gui With graphical user interface (required by some actions)"
## [1] " --batch-process Close GUI after executing all actions"
## [1] " --\b\b "
## [1] " --shell Start Inkscape in interactive shell mode"
## [1] ""
## [1] ""
## [1] "Examples:"
## [1] " Export input SVG (in.svg) to PDF (out.pdf) format:"
## [1] "\tinkscape --export-filename=out.pdf in.svg"
## [1] " Export input files (in1.svg, in2.svg) to PNG format keeping original name (in1.png, in2.png):"
## [1] "\tinkscape --export-type=png in1.svg in2.svg"
## [1] " See 'man inkscape' and http://wiki.inkscape.org/wiki/index.php/Using_the_Command_Line for more details."